package admin

import (
	"context"
	"kstar-gf-api/internal/dao"
	"kstar-gf-api/internal/model"
	"kstar-gf-api/internal/model/entity"
	"kstar-gf-api/internal/service"
	"kstar-gf-api/library/utils"

	"github.com/gogf/gf/v2/container/gmap"
	"github.com/gogf/gf/v2/os/gtime"
	"github.com/gogf/gf/v2/util/gconv"
)

type sTenantAdmin struct{}

func init() {
	service.RegisterTenantAdmin(New())
}

func New() *sTenantAdmin {
	return &sTenantAdmin{}
}

// 获取管理员下的租户及角色列表
func (s *sTenantAdmin) GetTenantAdminList(ctx context.Context, in *model.GetTenantAdminListInput, page int, pageSize int) (list []*model.TenantAdminInfoOutput, count int, err error) {
	count = 0
	list = make([]*model.TenantAdminInfoOutput, 0)

	where := gmap.New()
	if in.TenantId != "" {
		where.Set(dao.SysTenantAdmin.Columns().TenantId, in.TenantId)
	}
	if in.UserId != "" {
		where.Set(dao.SysTenantAdmin.Columns().UserId, in.UserId)
	}
	if in.UserName != "" {
		where.Set(dao.SysTenantAdmin.Columns().UserName+" LIKE ", "%"+in.UserName+"%")
	}
	if in.UserPhone != "" {
		where.Set(dao.SysTenantAdmin.Columns().UserPhone+" LIKE ", "%"+in.UserPhone+"%")
	}

	if pageSize > -1 {
		err = dao.SysTenantAdmin.Ctx(ctx).Where(where).OrderDesc(dao.SysTenantAdmin.Columns().CreateTime).WithAll().Page(page, pageSize).ScanAndCount(&list, &count, true)
	} else {
		err = dao.SysTenantAdmin.Ctx(ctx).Where(where).OrderDesc(dao.SysTenantAdmin.Columns().CreateTime).WithAll().Scan(&list)
	}
	if err != nil {
		return
	}

	// 查询角色列表
	roleList, _, _ := service.Role().GetRoleList(ctx, &model.RoleListInput{}, 0, -1)

	for _, admin := range list {
		RoleIdArray, err := utils.SplitAndConvert(admin.RoleIds, ",", func(s string) (int64, error) {
			return gconv.Int64(s), nil
		})
		RoleNameArray := make([]string, 0)
		if err == nil {
			admin.RoleIdArray = RoleIdArray
			for _, role := range roleList {
				if utils.InArray(role.RoleId, RoleIdArray) {
					RoleNameArray = append(RoleNameArray, role.RoleName)
				}
			}
		}
		admin.RoleNames = utils.Implode(RoleNameArray, ",")
	}

	return
}

// 更新最后登录时间
func (s *sTenantAdmin) UpdateLastLoginTime(ctx context.Context, userId, tenantId string) (err error) {
	where := gmap.New()
	where.Set(dao.SysTenantAdmin.Columns().UserId, userId)
	where.Set(dao.SysTenantAdmin.Columns().TenantId, tenantId)

	data := gmap.New()
	data.Set(dao.SysTenantAdmin.Columns().LastLoginTime, gtime.Now().Format("Y-m-d H:i:s"))

	_, err = dao.SysTenantAdmin.Ctx(ctx).Where(where).Data(data).Update()

	return
}

// 获取最后一次登录的租户信息
func (s *sTenantAdmin) GetLastLoginTenant(ctx context.Context, userId string) (info *model.LastLoginInfo, err error) {
	list := make([]*entity.SysTenantAdmin, 0)
	err = dao.SysTenantAdmin.Ctx(ctx).Where(dao.SysTenantAdmin.Columns().UserId, userId).OrderDesc(dao.SysTenantAdmin.Columns().LastLoginTime).Limit(1).Scan(&list)

	for key, item := range list {
		if key == 0 || item.LastLoginTime != nil {
			roleIdArray, _ := utils.SplitAndConvert(item.RoleIds, ",", func(s string) (int64, error) {
				return gconv.Int64(s), nil
			})
			// 没有权限则说明数据产生了错误，跳过，由控制器返回错误
			if len(roleIdArray) == 0 {
				continue
			}
			// 如果不是第0个租户，则跳过
			if key != 0 {
				continue
			}

			info = &model.LastLoginInfo{
				UserId:   item.UserId,
				TenantId: item.TenantId,
				RoleIds:  item.RoleIds,
			}

			// 查询角色列表
			roleList, _, _ := service.Role().GetRoleList(ctx, &model.RoleListInput{}, 0, -1)

			RoleNameArray := make([]string, 0)
			if err == nil {
				for _, role := range roleList {
					if utils.InArray(role.RoleId, roleIdArray) {
						RoleNameArray = append(RoleNameArray, role.RoleName)
					}
				}
			}
			info.RoleNames = utils.Implode(RoleNameArray, ",")

			tenantInfo, _ := service.Tenant().GetTenantInfo(ctx, item.TenantId)
			info.TenantName = tenantInfo.TenantName

			if item.LastLoginTime != nil {
				break
			}
		}
	}

	return
}

// 获取管理员角色信息
func (s *sTenantAdmin) GetTenantAdminInfo(ctx context.Context, userId string, tenantId string) (info *model.TenantAdminInfoOutput, err error) {
	where := gmap.New()
	where.Set(dao.SysTenantAdmin.Columns().UserId, userId)
	where.Set(dao.SysTenantAdmin.Columns().TenantId, tenantId)
	err = dao.SysTenantAdmin.Ctx(ctx).Where(where).WithAll().Scan(&info)
	if err != nil {
		return
	}

	if info != nil {
		roleIdArray, _ := utils.SplitAndConvert(info.RoleIds, ",", func(s string) (int64, error) {
			return gconv.Int64(s), nil
		})

		info.RoleIdArray = roleIdArray
		roleList, _, _ := service.Role().GetRoleList(ctx, &model.RoleListInput{
			RoleIds: roleIdArray,
		}, 0, -1)

		RoleNameArray := make([]string, 0)
		for _, role := range roleList {
			if utils.InArray(role.RoleId, roleIdArray) {
				RoleNameArray = append(RoleNameArray, role.RoleName)
			}
		}
		info.RoleNames = utils.Implode(RoleNameArray, ",")
	}

	return
}
